﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ImmlPad.Plugins;
using VastPark.ID;
using System.Collections.ObjectModel;
using Metaforik;
using VastPark.ID.Design;

namespace VastParkIDPlugin
{
    /// <summary>
    /// Interaction logic for VastParkIDPlugin.xaml
    /// </summary>
    [Plugin(
        Name = "VastPark Index",
        Icon = "pack://application:,,,/VastPark.ID.Design;component/Images/vp-id.png",
        Description = "Queries the VastPark Index",
        ModifierKeys = ModifierKeys.Control,
        Key = Key.I
     )]
    public partial class PluginUI : UserControl
    {
        private readonly string AUTH_PATH = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\ImmlPad\\VastParkID.auth";

        public ObservableCollection<Item> Results
        {
            get { return (ObservableCollection<Item>)GetValue(ResultsProperty); }
            set { SetValue(ResultsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Results.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ResultsProperty =
            DependencyProperty.Register("Results", typeof(ObservableCollection<Item>), typeof(PluginUI), new UIPropertyMetadata(new ObservableCollection<Item>()));


        public Profile Profile
        {
            get { return (Profile)GetValue(ProfileProperty); }
            set { SetValue(ProfileProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Profile.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ProfileProperty =
            DependencyProperty.Register("Profile", typeof(Profile), typeof(PluginUI), new UIPropertyMetadata(VastPark.ID.Design.DefaultProfile.Instance));

        private LoginProvider _LoginProvider;

        public PluginUI()
        {
            InitializeComponent();

            _LoginProvider = new LoginProvider();
        }

        private void _SearchBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return || e.Key == Key.Enter)
            {
                this.Results.Clear();
                _SearchingText.Visibility = System.Windows.Visibility.Visible;
                _SearchBox.IsEnabled = false;

                var response = LoginProvider.ProfileService.Find(_SearchBox.Text);
                foreach (var serviceItem in response.Data)
                {
                    var mfItem = (Metaforik.Design.Adapters.MetaforikServiceItem)serviceItem;
                    var items = mfItem.GetItems();

                    foreach (var item in items)
                    {
                        this.Results.Add(item);
                    }
                }

                _SearchBox.IsEnabled = true;
                _SearchingText.Visibility = System.Windows.Visibility.Collapsed;
                _ResultsCountText.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var dialog = new VastPark.ID.Design.UserDialog(_LoginProvider, AUTH_PATH, false);
            dialog.ShowDialog();

            if (_LoginProvider.UserProfile != null)
            {
                this.Profile = _LoginProvider.UserProfile.CurrentProfile;
                _NotLoggedIn.Visibility = System.Windows.Visibility.Collapsed;
                _LoggedIn.Visibility = System.Windows.Visibility.Visible;
                _SearchBox.IsEnabled = true;
            }
        }

        private void CopyLink_Click(object sender, RoutedEventArgs e)
        {
            var item = _ResultsList.SelectedItem as Item;
            var uri = _GetUri(item);
            Clipboard.SetText(uri);
        }

        private static string _GetUri(Item item)
        {
            return "http://id.vastpark.com/VastParkWS/get.vpws?name=" + item.Name + "&amp;publisher=" + item.Publisher + "&amp;domain=vastpark&amp;context=park";
        }

        private void _ResultsList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var item = (_ResultsList.SelectedItem as Item);
            var type = Metaforik.MetaforikUtil.ParseType(item.Assets[0].Type);

            var imml = string.Empty;
            switch (type)
            {
                case ItemType.Model:
                    {
                        imml = "<Model Source=\"" + _GetUri(item) + "\" Name=\"" + item.Name + "\" />\r\n";
                        break;
                    }
                case ItemType.Background:
                    {
                        imml = "<Background Source=\"" + _GetUri(item) + "\" Name=\"" + item.Name + "\" />\r\n";
                        break;
                    }
                case ItemType.Plugin:
                    {
                        imml = "<Plugin Source=\"" + _GetUri(item) + "\" Name=\"" + item.Name + "\" />\r\n";
                        break;
                    }
                case ItemType.Shader:
                    {
                        imml = "<Primitive Name=\"Shader Host\">\r\n" +
                                    "\t<MaterialGroup Id=\"-1\">\r\n" +
                                        "\t\t<Shader Source=\"" + _GetUri(item) + "\" />\r\n" +
                                    "\t</MaterialGroup>\r\n" +
                                "</Primitive>\r\n";

                        break;
                    }
                case ItemType.Sound:
                    {
                        imml = "<Sound Source=\"" + _GetUri(item) + "\" Name=\"" + item.Name + "\" />\r\n";
                        break;
                    }
                case ItemType.Video:
                    {
                        imml = "<Primitive Name=\"Video Host\">\r\n" +
                                       "\t<MaterialGroup Id=\"-1\">\r\n" +
                                           "\t\t<Video Source=\"" + _GetUri(item) + "\" />\r\n" +
                                       "\t</MaterialGroup>\r\n" +
                                   "</Primitive>\r\n";

                        break;
                    }
                case ItemType.Widget:
                    {
                        imml = "<Widget Source=\"" + _GetUri(item) + "\" Name=\"" + item.Name + "\" />\r\n";
                        break;
                    }
            }

            ImmlPadPlugins.EditorInfo.Editor.InsertStringAtCaret(imml);
        }

        private void This_Loaded(object sender, RoutedEventArgs e)
        {
            if (System.IO.File.Exists(AUTH_PATH))
            {
                var username = string.Empty;
                var password = string.Empty;

                _LoggingIn.Visibility = System.Windows.Visibility.Visible;
                _NotLoggedIn.Visibility = System.Windows.Visibility.Collapsed;

                System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(delegate
                {
                    CredentialSerialiser.Read(AUTH_PATH, out username, out password);

                    try
                    {
                        var response = _LoginProvider.Login(username, password, true);

                        if (response.HasError)
                        {
                            Dispatcher.Invoke((System.Threading.ThreadStart)delegate
                            {
                                _LoggingIn.Visibility = System.Windows.Visibility.Collapsed;
                                _NotLoggedIn.Visibility = System.Windows.Visibility.Visible;
                            });
                        }
                        else
                        {
                            Dispatcher.Invoke((System.Threading.ThreadStart)delegate
                            {
                                this.Profile = response.Data.CurrentProfile;
                                _LoggingIn.Visibility = System.Windows.Visibility.Collapsed;
                                _LoggedIn.Visibility = System.Windows.Visibility.Visible;
                                _SearchBox.IsEnabled = true;
                            });
                        }
                    }
                    catch
                    {
                        //error logging in
                        Dispatcher.Invoke((System.Threading.ThreadStart)delegate
                        {
                            _LoggingIn.Visibility = System.Windows.Visibility.Collapsed;
                            _NotLoggedIn.Visibility = System.Windows.Visibility.Visible;
                        });
                    }
                }));
            }
        }
    }
}
